using Microsoft.SqlServer.Management.Sdk.Sfc;
using System;
using System.Collections.Generic;

namespace Microsoft.SqlServer.Management.SqlManagerUI.Scripting
{
	internal class SingleScriptTarget : ScriptTarget
	{
		private ScriptHandler scriptHandler;

		private ScriptWriterFactory scriptWriterFactory;

		public override EventHandler<ObjectScriptedEventArgs> ObjectScriptedHandler
		{
			get
			{
				return new EventHandler<ObjectScriptedEventArgs>(this.OnObjectScripted);
			}
		}

		public override EventHandler ScriptingFinishedHandler
		{
			get
			{
				return new EventHandler(this.OnScriptingFinished);
			}
		}

		public SingleScriptTarget(IEnumerable<Urn> createDependencyList, IEnumerable<Urn> dropDependencyList, ScriptWriterFactory scriptWriterFactory)
		{
			if (createDependencyList == null)
			{
				createDependencyList = new Urn[0];
			}
			if (dropDependencyList == null)
			{
				dropDependencyList = new Urn[0];
			}
			if (scriptWriterFactory == null)
			{
				throw new ArgumentNullException("scriptWriterFactory");
			}
			this.scriptWriterFactory = scriptWriterFactory;
			this.SetupScriptHandlers(createDependencyList, dropDependencyList);
		}

		private void OnObjectScripted(object source, ObjectScriptedEventArgs e)
		{
			if (e == null)
			{
				throw new ArgumentNullException("e");
			}
			this.scriptHandler.HandleScriptedEvent(e);
		}

		private void OnScriptingFinished(object source, EventArgs e)
		{
			using (ScriptWriter scriptWriter = this.GetScriptWriter())
			{
				scriptWriter.WritingObject += new EventHandler<ScriptingProgressEventArgs>(base.OnWritingObject);
				this.scriptHandler.Script(scriptWriter);
			}
		}

		protected void SetupScriptHandlers(IEnumerable<Urn> createDependencyList, IEnumerable<Urn> dropDependencyList)
		{
			IEnumerable<Urn> objectOrder = SingleScriptTarget.FilterDropDependencyList(dropDependencyList);
			ScriptHandler successor = new ObjectScriptHandler("DdlTrigger", ScriptActions.Header | ScriptActions.EnableDDLTrigger);
			successor = new ObjectScriptHandler("DdlTrigger", ScriptActions.Permission | ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler(null, ScriptActions.Permission, successor);
			successor = new DefaultDatabaseObjectScriptHandler(ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("ForeignKey", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Check", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Default", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("UserDefinedDataType", ScriptActions.Header | ScriptActions.Bindings, successor);
			successor = new DependencyScriptHandler(createDependencyList, ScriptActions.Create | ScriptActions.Header | ScriptActions.Data | ScriptActions.Bindings, successor);
			successor = new ObjectScriptHandler("FullTextCatalog", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Schema", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("User", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Role", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("ApplicationRole", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Login", ScriptActions.Create | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Login", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new DefaultDatabaseObjectScriptHandler(ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("ApplicationRole", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Role", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("User", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Schema", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("FullTextCatalog", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("Default", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new DependencyScriptHandler(objectOrder, ScriptActions.Drop | ScriptActions.Header | ScriptActions.DropData, successor);
			successor = new ObjectScriptHandler("Check", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("ForeignKey", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("DdlTrigger", ScriptActions.Drop | ScriptActions.Header, successor);
			successor = new ObjectScriptHandler("DdlTrigger", ScriptActions.Header | ScriptActions.DisableDDLTrigger, successor);
			successor = new ObjectScriptHandler("Database", ScriptActions.Create | ScriptActions.Header, successor);
			this.scriptHandler = successor;
		}

		private static IEnumerable<Urn> FilterDropDependencyList(IEnumerable<Urn> source)
		{
			List<Urn> list = new List<Urn>();
			foreach (Urn current in source)
			{
				if (current.Type != "Trigger")
				{
					list.Add(current);
				}
			}
			return list;
		}

		protected ScriptWriter GetScriptWriter()
		{
			return this.scriptWriterFactory.GetScriptWriter();
		}
	}
}
